package com.hy.codesandbox;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import com.hy.codesandbox.model.ExecuteCodeRequest;
import com.hy.codesandbox.model.ExecuteCodeResponse;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * Created With IntelliJ IDEA.
 * Descriptions:
 * User:Mr.Du
 * Date:2023/10/26
 * Time:20:36
 */
public class JavaNativeSandBox implements CodeSandBox{


    private static final String GLOBAL_CODE_DIR_NAME = "tmpCode";

    private static final String GLOBAL_JAVA_CLASS_NAME = "Main.java";

    private static final long TIME_OUT = 5000L;

    public static void main(String[] args) {
        JavaCodeSandboxTemplate javaNativeSandBox = new JavaCodeSandboxTemplate();
        ExecuteCodeRequest executeCodeRequest = new ExecuteCodeRequest();
        executeCodeRequest.setLanguage("java");
        executeCodeRequest.setInputList(Arrays.asList("1 2", "3 4"));
        String code = ResourceUtil.readStr("testCode/Main.java", StandardCharsets.UTF_8);
        executeCodeRequest.setCode(code);
        javaNativeSandBox.executeCode(executeCodeRequest);
    }
    @Override
    public ExecuteCodeResponse executeCode(ExecuteCodeRequest executeCodeRequest) {
        List<String> inputList = executeCodeRequest.getInputList();
        String code = executeCodeRequest.getCode();
        String language = executeCodeRequest.getLanguage();

        // 1. 把用户的代码保存为文件
        File userCodeFile = saveCodeToFile(code);

        String compileCmd = String.format("javac -encoding utf-8 %s", userCodeFile.getAbsolutePath());
        try {
            Process exec = Runtime.getRuntime().exec(compileCmd);
            int exitValue = exec.waitFor();
            if(exitValue == 0){
                System.out.println("编译成功");
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(exec.getInputStream()));
                String br;
                while((br = bufferedReader.readLine()) != null){
                    System.out.println(br);
                }
            }else{
                System.out.println("编译失败，错误码为: " + exitValue);
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(exec.getErrorStream()));
                String br;
                while((br = bufferedReader.readLine()) != null){
                    System.out.println(br);
                }
                BufferedReader errorBufferedReader = new BufferedReader(new InputStreamReader(exec.getErrorStream()));
                String errorBr;
                while((errorBr = errorBufferedReader.readLine()) != null){
                    System.out.println(errorBr);
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    /**
     * 1. 把用户的代码保存为文件
     * @param code 用户代码
     * @return
     */
    public File saveCodeToFile(String code) {
        String userDir = System.getProperty("user.dir");
        String globalCodePathName = userDir + File.separator + GLOBAL_CODE_DIR_NAME;
        // 判断全局代码目录是否存在，没有则新建
        if (!FileUtil.exist(globalCodePathName)) {
            FileUtil.mkdir(globalCodePathName);
        }

        // 把用户的代码隔离存放
        String userCodeParentPath = globalCodePathName + File.separator + UUID.randomUUID();
        String userCodePath = userCodeParentPath + File.separator + GLOBAL_JAVA_CLASS_NAME;
        File userCodeFile = FileUtil.writeString(code, userCodePath, StandardCharsets.UTF_8);
        System.out.println(userCodeFile.getAbsolutePath());
        return userCodeFile;
    }
}
